home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
051-060
/
amok59
/
menu
/
menu.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
10KB
|
422 lines
MODULE Menu;
(*------ importlist: ------*)
IMPORT sys := SYSTEM,
g := Graphics,
str := Strings,
I := Intuition;
(*------ Globals: ------*)
VAR
oom*: PROCEDURE(); (* Wird bei Speichermangel aufgerufen, sollte entweder
versuchen, Speicher freizugeben und zurückkehren, oder
das Programm abbrechen. *)
FirstMenu,LastMenu: I.MenuPtr; (* Erster und letzter Menüstreifen *)
LastItem: I.MenuItemPtr; (* Zuletzt erzeugtes Item *)
leftBase: INTEGER; (* linke Kante des Menütitels *)
height: INTEGER; (* Höhe des Menüs *)
ItemWidth: INTEGER; (* Breite des breitesten Itemtextes *)
ItemWidth2: INTEGER; (* Breite des breitesten Itemtextes 2 *)
rp: g.RastPortPtr; (* RastPort des Screens *)
screen: I.ScreenPtr; (* Der Screen selbst *)
commandWidth: INTEGER;(* Breite des Breitetsten Command-Keys *)
(*------ Menü Starten Menue: ------*)
PROCEDURE StartMenu*(win: I.WindowPtr);
(* Diese Prozedur muß vor allen anderen Prozeduren dieses Moduls aufgerufen werden. *)
BEGIN
leftBase := 0;
FirstMenu := NIL;
LastMenu := NIL;
screen := win.wScreen;
rp := sys.ADR(screen.rastPort);
END StartMenu;
(*------ EndStrip: ------*)
PROCEDURE EndStrip;
(* Interne Prozedur, beendet aktuelle Menuleiste und setzt Breite der Items *)
VAR
it: I.IntuiTextPtr;
im: I.ImagePtr;
top, left,height,width: INTEGER;
BEGIN
INC(ItemWidth,g.TextLength(rp,"M",1));
INC(commandWidth,I.commWidth);
IF commandWidth>ItemWidth2 THEN ItemWidth2 := commandWidth END;
LastItem := LastMenu.firstItem;
left := 0; height := 0; width := ItemWidth + ItemWidth2 + 2;
WHILE LastItem#NIL DO
LastItem.width := width;
height := LastItem.topEdge + LastItem.height;
INC(LastItem.leftEdge,left);
IF I.itemText IN LastItem.flags THEN
it := LastItem.itemFill;
it := it.nextText;
IF it#NIL THEN
it.leftEdge := LastItem.width-2;
DEC(it.leftEdge,g.TextLength(rp,it.iText^,str.Length(it.iText^)));
END;
ELSE
im := LastItem.itemFill;
im.width := ItemWidth+ItemWidth2;
END;
LastItem := LastItem.nextItem;
END;
IF height + screen.barHeight + 4 > screen.height THEN
LastItem := LastMenu.firstItem;
WHILE (LastItem#NIL) AND (LastItem.topEdge + LastItem.height < height DIV 2) DO
LastItem := LastItem.nextItem;
END;
IF LastItem#NIL THEN
left := height - LastItem.topEdge + LastItem.height;
IF left - (LastItem.topEdge + LastItem.height) >= LastItem.height THEN
LastItem := LastItem.nextItem;
END;
IF LastItem#NIL THEN
top := LastItem.topEdge;
left := width + 4; INC(width,left);
WHILE LastItem#NIL DO
DEC(LastItem.topEdge,top);
INC(LastItem.leftEdge,left);
LastItem := LastItem.nextItem;
END;
END;
END;
END;
IF width + LastMenu.leftEdge + 16 > screen.width THEN
DEC(width,screen.width - LastMenu.leftEdge - 16);
IF width > LastMenu.leftEdge THEN width := LastMenu.leftEdge END;
LastItem := LastMenu.firstItem;
WHILE (LastItem#NIL) DO
DEC(LastItem.leftEdge,width);
LastItem := LastItem.nextItem;
END;
END;
END EndStrip;
(*------ NewMenu: ------*)
PROCEDURE NewMenu*(name: ARRAY OF CHAR); (* $CopyArrays- *)
(* Startet neue Menüleiste. Parameter ist der Name dieses Menüs.
* NewMenu muß aufgerufen werden, bevor eine der Itemprozeduren
* (s.u.) aufgerufen wird.
*)
VAR
m: I.MenuPtr;
BEGIN
IF LastMenu#NIL THEN EndStrip END;
LOOP
NEW(m); IF m#NIL THEN EXIT END;
oom;
END;
IF FirstMenu=NIL THEN FirstMenu := m;
ELSE LastMenu.nextMenu := m END;
LastMenu := m;
m.leftEdge := leftBase;
m.topEdge := 0;
m.width := g.TextLength(rp,name,str.Length(name))+12;
INC(leftBase,m.width+10);
m.height := 0;
m.flags := {I.miDrawn,I.menuEnabled};
m.menuName := sys.ADR(name);
m.firstItem := NIL;
LastItem := NIL;
ItemWidth := 0;
ItemWidth2 := 0;
height := 0;
commandWidth := 0;
END NewMenu;
(*------ Item: ------*)
PROCEDURE Item(name: ARRAY OF CHAR;
name2: ARRAY OF CHAR;
com: CHAR;
checkmark,checked: BOOLEAN); (* $CopyArrays- *)
(* Interne Prozedur zum Erzeugen von Menuitems *)
VAR
t: I.MenuItemPtr;
it,it2: I.IntuiTextPtr;
w: INTEGER;
comstr: ARRAY 1 OF CHAR;
BEGIN
LOOP
NEW(t);
IF t#NIL THEN EXIT END;
oom;
END;
LOOP
NEW(it);
IF it#NIL THEN EXIT END;
oom;
END;
IF LastItem=NIL THEN LastMenu.firstItem := t
ELSE LastItem.nextItem := t END;
LastItem := t;
t.leftEdge := 2;
t.topEdge := height;
w := g.TextLength(rp,name,str.Length(name));
IF checkmark THEN INC(w,I.checkWidth) END;
IF w>ItemWidth THEN ItemWidth := w END;
t.height := rp.font.ySize+2;
INC(height,t.height + t.height DIV 10);
t.flags := {I.itemText,I.itemEnabled,I.highComp};
IF checkmark THEN
t.flags := t.flags + {I.checkIt,I.menuToggle};
IF checked THEN INCL(t.flags,I.checked) END;
END;
IF com#0X THEN
INCL(t.flags,I.commSeq);
comstr[0] := com;
w := g.TextLength(rp,comstr,1);
IF w>commandWidth THEN commandWidth := w END;
END;
t.mutualExclude := LONGSET{};
t.itemFill := it;
t.selectFill:= NIL;
t.command := com; t.subItem := NIL;
it.frontPen := screen.detailPen; it.backPen := screen.blockPen;
it.drawMode := g.jam2;
it.iTextFont:= NIL;
it.topEdge := 1;
it.leftEdge := 2;
IF checkmark THEN INC(it.leftEdge,I.checkWidth) END;
it.iText := sys.ADR(name);
IF name2[0]#0X THEN
LOOP
NEW(it2);
IF it2#NIL THEN EXIT END;
oom;
END;
it2^ := it^;
it2.iText := sys.ADR(name2);
it.nextText := it2;
w := g.TextLength(rp,name2,str.Length(name2));
IF w>ItemWidth2 THEN ItemWidth2 := w END;
END;
END Item;
(*------ NewItem: ------*)
PROCEDURE NewItem*(name: ARRAY OF CHAR;
com: CHAR); (* $CopyArrays- *)
(* erzeugt neues Menuitem mit Namen name und Tastatur-Shortcut Amiga+com.
* Ist com=0X hat dieser Menüpunkt keine Tastaturabkürzung
*)
BEGIN
Item(name,"",com,FALSE,FALSE);
END NewItem;
(*------ NewItem2: ------*)
PROCEDURE NewItem2*(name: ARRAY OF CHAR;
name2: ARRAY OF CHAR); (* $CopyArrays- *)
(* erzeugt neues Menuitem mit Namen name und name2. name2 wird dabei
* rechtsbündig ins Menü eingefügt. Es sollte vor allem für Tastatur-
* abkürzungen wie '^Q' verwendet werden.
*)
BEGIN
Item(name,name2,0X,FALSE,FALSE);
END NewItem2;
(*------ NewItemChecked: ------*)
PROCEDURE NewItemChecked*(name: ARRAY OF CHAR;
com: CHAR;
checked: BOOLEAN); (* $CopyArrays- *)
(* erzeugt neues Menuitem mit Namen name und Tastatur-Shortcut Amiga+com.
* Ist com=0X hat dieser Menüpunkt keine Tastaturabkürzung. Dieses Menü
* bekommt ein Häkchen. Ist checked=TRUE, wird dieses Häkchen gleich
* gesetzt.
*)
BEGIN
Item(name,"",com,TRUE,checked);
END NewItemChecked;
(*------ NewItemChecked: ------*)
PROCEDURE NewItem2Checked*(name: ARRAY OF CHAR;
name2: ARRAY OF CHAR;
checked: BOOLEAN); (* $CopyArrays- *)
(* erzeugt neues Menuitem mit Namen name und name2. name2 wird dabei
* rechtsbündig ins Menü eingefügt. Es sollte vor allem für Tastatur-
* abkürzungen wie '^Q' * verwendet werden. Dieses Menü bekommt ein
* Häkchen. Ist checked=TRUE, wird dieses Häkchen gleich gesetzt.
*)
BEGIN
Item(name,name2,0X,TRUE,checked);
END NewItem2Checked;
(*------ Seperator: ------*)
PROCEDURE Seperator*;
(* Erzeugt Linie *)
VAR
t: I.MenuItemPtr;
im: I.ImagePtr;
comstr: ARRAY 1 OF CHAR;
BEGIN
LOOP
NEW(t);
IF t#NIL THEN EXIT END;
oom;
END;
LOOP
NEW(im);
IF im#NIL THEN EXIT END;
oom;
END;
IF LastItem=NIL THEN LastMenu.firstItem := t
ELSE LastItem.nextItem := t END;
LastItem := t;
t.leftEdge := 2;
t.topEdge := height;
t.height := 5;
INC(height,5);
t.flags := I.highNone;
t.mutualExclude := LONGSET{};
t.itemFill := im;
t.selectFill:= NIL;
t.command := 0X;
t.subItem := NIL;
im.leftEdge := 1;
im.topEdge := 1;
im.width := 0;
im.height := 2;
im.depth := 0;
im.imageData:= NIL;
im.planePick:= SHORTSET{};
im.planeOnOff:= SHORTSET{};
im.nextImage:= NIL;
END Seperator;
(*------ EndMenu: ------*)
PROCEDURE EndMenu*(): I.MenuPtr;
(* Beendet das Menü und gibt einen Zeiger auf die Menüstruktur zurück. Das Ergebnis
* ist #NIL wenn NewMenu() mindestens einmal aufgerufen wurde.
*)
BEGIN
EndStrip;
RETURN FirstMenu;
END EndMenu;
(*------ EndMenu: ------*)
PROCEDURE DisposeMenu*(m: I.MenuPtr);
(* Gibt den Speicher des Menüs wieder frei: *)
PROCEDURE DisposeText(t: I.IntuiTextPtr);
BEGIN
IF t#NIL THEN
DisposeText(t.nextText);
DISPOSE(t);
END;
END DisposeText;
PROCEDURE DisposeImage(i: I.ImagePtr);
BEGIN
IF i#NIL THEN
DisposeImage(i.nextImage);
DISPOSE(i);
END;
END DisposeImage;
PROCEDURE DisposeItem(i: I.MenuItemPtr);
BEGIN
IF i#NIL THEN
DisposeItem(i.nextItem);
IF I.itemText IN i.flags THEN DisposeText (i.itemFill)
ELSE DisposeImage(i.itemFill) END;
DISPOSE(i);
END;
END DisposeItem;
BEGIN
IF m#NIL THEN
DisposeMenu(m.nextMenu);
DisposeItem(m.firstItem);
DISPOSE(m);
END;
END DisposeMenu;
(*------ OOM: ------*)
PROCEDURE * OOM;
(* Voreingestellte Prozedur für oom:
*)
BEGIN
HALT(20);
END OOM;
(*------ Initialisierung: ------*)
BEGIN
oom := OOM;
END Menu.